<template><div><h1 id="实现监听元素大小的指令" tabindex="-1"><a class="header-anchor" href="#实现监听元素大小的指令" aria-hidden="true">#</a> 实现监听元素大小的指令</h1>
<p>在<code v-pre>utils</code>文件夹内创建一个<code v-pre>elSizeDirective.js</code>文件，用于存放我们实现监听元素大小指令的代码</p>
<!--  -->
<div class="language-javascript line-numbers-mode" data-ext="js"><pre v-pre class="language-javascript"><code><span class="token comment">// 创建一个 WeakMap 数组来存放 使用该指令的元素 和 该指令绑定的回调函数 的映射关系</span>
<span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 创建监听尺寸大小的观察器</span>
<span class="token keyword">const</span> ob <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ResizeObserver</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">entries</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
	<span class="token doc-comment comment">/**
	 * entries是正在被监听的元素数组
	 * 通过for循环我们可以拿到每一个正在被监听的元素
	 */</span>
	<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> entry <span class="token keyword">of</span> entries<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 在映射关系数组中获取到对应绑定的函数</span>
		<span class="token keyword">const</span> handler <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>entry<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token comment">// 如果函数存在就调用该函数</span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span>handler<span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token comment">// 将元素的大小传给该函数</span>
			<span class="token function">handler</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
				<span class="token literal-property property">width</span><span class="token operator">:</span> entry<span class="token punctuation">.</span>borderBoxSize<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>inlineSize<span class="token punctuation">,</span>
				<span class="token literal-property property">height</span><span class="token operator">:</span> entry<span class="token punctuation">.</span>borderBoxSize<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>blockSize<span class="token punctuation">,</span>
			<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
	<span class="token function">mounted</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 当使用该指令的元素挂在时触发</span>

		<span class="token comment">// 创建映射管理 键为元素 值为绑定的函数</span>
		map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>el<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token comment">// 开始观察该元素的大小</span>
		ob<span class="token punctuation">.</span><span class="token function">observe</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span><span class="token punctuation">,</span>
	<span class="token function">unmounted</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 当元素被卸载的时候，取消掉对该元素大小的观察</span>
		ob<span class="token punctuation">.</span><span class="token function">unobserve</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在<code v-pre>main.js</code>中注册指令：</p>
<div class="language-javascript line-numbers-mode" data-ext="js"><pre v-pre class="language-javascript"><code><span class="token keyword">import</span> sizeOb <span class="token keyword">from</span> <span class="token string">'@/utils/elSizeDirective'</span><span class="token punctuation">;</span>

app<span class="token punctuation">.</span><span class="token function">directive</span><span class="token punctuation">(</span><span class="token string">'size-ob'</span><span class="token punctuation">,</span> sizeOb<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></div></template>


